home *** CD-ROM | disk | FTP | other *** search
- /* cfengine for GNU
-
- Copyright (C) 1995
- Free Software Foundation, Inc.
-
- This file is part of GNU cfengine - written and maintained
- by Mark Burgess, Dept of Computing and Engineering, Oslo College,
- Dept. of Theoretical physics, University of Oslo
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
- */
-
-
- /*******************************************************************/
- /* */
- /* Process handling */
- /* */
- /*******************************************************************/
-
-
- #include "cf.defs.h"
- #include "cf.extern.h"
-
- int DEADLOCK = false;
- FILE *PIPE;
-
- /*******************************************************************/
-
- LoadProcessTable(procdata,psopts)
-
- struct Item **procdata;
- char *psopts;
-
- { FILE *pp;
- char pscomm[maxlinksize];
-
- sprintf(pscomm,"%s %s",VPSCOMM[VSYSTEMHARDCLASS],psopts);
-
- Verbose("%s: Running process command %s\n",VPREFIX,pscomm);
-
- if ((pp = cfpopen(pscomm,"r")) == NULL)
- {
- sprintf(OUTPUT,"Couldn't open the process list with command %s\n",pscomm);
- CfLog(cferror,OUTPUT,"popen");
- return false;
- }
-
- while (!feof(pp))
- {
- ReadLine(VBUFF,bufsize,pp);
- AppendItem(procdata,VBUFF,"");
- }
-
- cfpclose(pp);
- return true;
- }
-
- /*******************************************************************/
-
- DoProcessCheck(pp,procdata)
-
- struct Process *pp;
- struct Item *procdata;
-
- { struct Item *ip, *ip2;
- char *err, line[bufsize], *sp;
- int match, pid=-1, ret, matches=0, got;
- int BreakPipe();
- FILE *pipe;
- regex_t rx,rxcache;
- regmatch_t pmatch;
- size_t nmatch = 1;
- pid_t cfengine_pid = getpid();
-
- Debug2("Looking for process %s\n",pp->expr);
-
- if (regcomp(&rxcache,pp->expr,REG_EXTENDED) != 0)
- {
- sprintf(OUTPUT,"Regular expression error for process pattern %s\n",pp->expr);
- CfLog(cferror,OUTPUT,"");
- sprintf(OUTPUT,"%s\n",err);
- CfLog(cferror,OUTPUT,"");
- return;
- }
-
- for (ip = procdata; ip != NULL; ip=ip->next)
- {
- bcopy(&rxcache,&rx,sizeof(rx)); /* To fix a bug on some implementations where rx gets emptied */
- if (regexec(&rx,ip->name,1,&pmatch,0) == 0)
- {
- pid = -1;
- got = true;
-
- for (ip2 = pp->inclusions; ip2 != NULL; ip2 = ip2->next)
- {
- got = false;
-
- if (strstr(ip->name,ip2->name))
- {
- got = true;
- break;
- }
- }
-
- if (!got)
- {
- continue;
- }
-
- got = false;
-
- for (ip2 = pp->exclusions; ip2 != NULL; ip2 = ip2->next)
- {
- if (strstr(ip->name,ip2->name))
- {
- got = true;
- break;
- }
- }
-
- if (got)
- {
- continue;
- }
-
- for (sp = ip->name; *sp != '\0'; sp++) /* if first field contains alpha, skip */
- {
- while (true)
- {
- while (!isdigit(*sp) && (*sp != '\0'))
- {
- sp++;
- }
-
- if ((sp > ip->name) && isalnum(*(sp-1))) /* Username contains number*/
- {
- sp++;
- }
- else
- {
- break;
- }
- }
-
- sscanf(sp,"%d",&pid);
-
- if (pid != -1)
- {
- break;
- }
- }
-
- if (pid == -1)
- {
- sprintf(OUTPUT,"Unable to extract pid while looking for %s\n",pp->expr);
- CfLog(cfverbose,OUTPUT,"");
- continue;
- }
-
- Debug2("Found matching pid %d\n",pid);
-
- matches++;
-
- if (pid == 1 && pp->signal == cfhup)
- {
- Verbose("(Okay to send HUP to init)\n");
- }
- else if (pid < 4)
- {
- Verbose("%s: will not signal or restart processes 0,1,2,3\n",VPREFIX);
- Verbose("%s: occurred while looking for %s\n",VPREFIX,pp->expr);
- continue;
- }
-
- if (pp->action == 'w')
- {
- sprintf(OUTPUT,"Process warning, found: %s\n",ip->name);
- CfLog(cfinform,OUTPUT,"");
- continue;
- }
-
- if (pp->signal != cfnosignal)
- {
- sprintf(OUTPUT,"Signalling process %d (%s) with %s\n",pid,pp->expr,SIGNALS[pp->signal]);
- CfLog(cfinform,OUTPUT,"");
-
- if (!DONTDO)
- {
- if (pid == cfengine_pid)
- {
- CfLog(cfverbose,"Cfengine will not kill itself!\n","");
- }
- else if ((ret = kill((pid_t)pid,pp->signal)) < 0)
- {
- sprintf(OUTPUT,"Couldn't send signal to pid %d\n",pid);
- CfLog(cfverbose,OUTPUT,"kill");
-
- continue;
- }
-
- if ((pp->signal == cfkill || pp->signal == cfterm) && ret >= 0)
- {
- sprintf(OUTPUT,"Killed: %s\n",ip->name);
- CfLog(cfinform,OUTPUT,"");
- }
- }
- }
- }
- }
-
- if (matches > 0)
- {
- Verbose("Defining classes %s\n",pp->defines);
- AddMultipleClasses(pp->defines);
- }
-
- if (pp->matches >= 0)
- {
- switch (pp->comp)
- {
- case '=': if (matches != (int)pp->matches)
- {
- sprintf(OUTPUT,"%d processes matched %s (should be %d)\n",matches,pp->expr,pp->matches);
- CfLog(cferror,OUTPUT,"");
- }
- break;
-
- case '>': if (matches < (int)pp->matches)
- {
- sprintf(OUTPUT,"%d processes matched %s (should be >=%d)\n",matches,pp->expr,pp->matches);
- CfLog(cferror,OUTPUT,"");
- }
- break;
-
- case '<': if (matches > (int)pp->matches)
- {
- sprintf(OUTPUT,"%d processes matched %s (should be <=%d)\n",matches,pp->expr,pp->matches);
- CfLog(cferror,OUTPUT,"");
- }
- }
- }
-
- if (strlen(pp->restart) != 0)
- {
- if ((matches != 0) && (pp->signal != cfkill) && (pp->signal != cfterm))
- {
- Verbose("%s: Matches found for %s - no restart sequence\n",VPREFIX,pp->expr);
- regfree(&rx);
- return;
- }
-
- sprintf(OUTPUT,"Executing shell command: %s\n",pp->restart);
- CfLog(cfinform,OUTPUT,"");
-
- if (DONTDO)
- {
- regfree(&rx);
- return;
- }
-
- if (pp->useshell == 'y')
- {
- if ((PIPE = popen(pp->restart,"r")) == NULL)
- {
- sprintf(OUTPUT,"Process restart execution failed on %s\n",pp->restart);
- CfLog(cferror,OUTPUT,"popen");
- regfree(&rx);
- return;
- }
- }
- else
- {
- if ((PIPE = cfpopen(pp->restart,"r")) == NULL)
- {
- sprintf(OUTPUT,"Process restart execution failed on %s\n",pp->restart);
- CfLog(cferror,OUTPUT,"popen");
- regfree(&rx);
- return;
- }
- }
-
- DEADLOCK = false;
-
- while (!feof(PIPE))
- {
- if (pp->useshell == 'd') /* dumb shell */
- {
- fgets(line,1,PIPE);
- break;
- }
-
- ReadLine(line,bufsize,PIPE);
-
- if (feof(PIPE) || ferror(PIPE))
- {
- break;
- }
-
- if (strstr(line,"cfengine-die"))
- {
- break;
- }
-
- /* patch for ERESTARTSYSTEM bug in popen */
-
- if (strstr(line,"cfd: start") || DEADLOCK)
- {
- printf("");
- break;
- }
-
- sprintf(OUTPUT,"Restart: %s",line);
- CfLog(cfinform,OUTPUT,"");
- }
-
- if (pp->useshell == 'y')
- {
- pclose(PIPE);
- }
- else
- {
- cfpclose(PIPE);
- }
-
- sprintf(OUTPUT,"(Done with %s)\n",pp->restart);
- CfLog(cfinform,OUTPUT,"");
- }
-
- regfree(&rx);
- }
-
-